package jp.co.systemi.asp.workflow.report;

import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.logging.Logger;

import jp.co.systemi.asp.workflow.Main;
import jp.co.systemi.asp.workflow.annotation.FormInput;
import jp.co.systemi.asp.workflow.data.PaidHoliday;
import jp.co.systemi.asp.workflow.peer.PaidHolidayPeer;

import org.apache.wicket.PageParameters;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.markup.html.form.AjaxButton;
import org.apache.wicket.behavior.SimpleAttributeModifier;
import org.apache.wicket.extensions.markup.html.form.DateTextField;
import org.apache.wicket.extensions.yui.calendar.DatePicker;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.WebResource;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.link.ResourceLink;
import org.apache.wicket.markup.html.list.ListItem;
import org.apache.wicket.markup.html.list.ListView;
import org.apache.wicket.model.PropertyModel;
import org.apache.wicket.protocol.http.WebResponse;
import org.apache.wicket.util.resource.IResourceStream;
import org.apache.wicket.util.resource.StringResourceStream;

public class PaidHolidayReport extends Main {
    /**
     * ログ出力 クラス名をあわせること
     */
    private static final Logger log = Logger.getLogger(PaidHolidayReport.class
            .getName());
    public static final String CATEGORY = "有給休暇";
    List<PaidHoliday> holidays = new ArrayList<PaidHoliday>(); // 申請分または承認済みがまだ未消化（日付が過ぎてない）有給休暇一覧
    Date month = Calendar.getInstance().getTime();
    SimpleDateFormat sdf = new SimpleDateFormat("yyyyMM");
    // 有給休暇リスト
    final WebMarkupContainer tblHoliday = new WebMarkupContainer(
            "wi_tblPaidHoliday");
    @FormInput
    public DateTextField wi_month = new DateTextField("wi_month",
            new PropertyModel<Date>(this, "month"),
            getString("date.format.yyyyMM"));

    @FormInput
    public AjaxButton wi_btnPrevMonth = new AjaxButton("wi_btnPrevMonth") {
        private static final long serialVersionUID = -7836218856780103915L;

        @Override
        protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
            Calendar cal = Calendar.getInstance();
            cal.setTime(month);
            cal.add(Calendar.MONTH, -1);
            month = cal.getTime();

            cal = Calendar.getInstance();
            int backMonths = Integer.parseInt(getString("back.months")) - 1;
            cal.add(Calendar.MONTH, -backMonths);
            Date backLimit = cal.getTime();
            holidays = PaidHolidayPeer.getPaidHolidayData(month);

            if(sdf.format(month).compareTo(sdf.format(backLimit)) <= 0){
                wi_btnPrevMonth.setEnabled(false);
            }
            wi_btnNextMonth.setEnabled(true);
            target.addComponent(wi_month);
            target.addComponent(tblHoliday);
            target.addComponent(wi_btnPrevMonth);
            target.addComponent(wi_btnNextMonth);
        }

    };
    @FormInput
    public AjaxButton wi_btnNextMonth = new AjaxButton("wi_btnNextMonth") {
        private static final long serialVersionUID = -7836218856780103915L;

        @Override
        protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
            Calendar cal = Calendar.getInstance();
            Date now = cal.getTime();
            cal.setTime(month);
            cal.add(Calendar.MONTH, 1);
            month = cal.getTime();
            holidays = PaidHolidayPeer.getPaidHolidayData(month);

            wi_btnPrevMonth.setEnabled(true);
            if(sdf.format(month).compareTo(sdf.format(now)) >= 0 ){
                wi_btnNextMonth.setEnabled(false);
            }
            target.addComponent(wi_month);
            target.addComponent(tblHoliday);
            target.addComponent(wi_btnPrevMonth);
            target.addComponent(wi_btnNextMonth);
        }

    };

    /**
     * コンストラクター 画面の生成、イベント処理の定義はすべて、この中で完結する
     */
    public PaidHolidayReport() {
        init();
    }

    public PaidHolidayReport(PageParameters pars) {
        DateFormat foramt = new SimpleDateFormat("yyyyMM");
        try {
            month = foramt.parse(pars.getString("month"));
        } catch (ParseException e) {
            log.info(e.getLocalizedMessage());
        }
        init();
    }

    private String toCSV() {
        String header = getString("csv.header");
        SimpleDateFormat sdf = new SimpleDateFormat(header);
        header = sdf.format(month);
        StringBuffer sb = new StringBuffer(header).append("\r\n");
        for (PaidHoliday holiday : holidays) {
            sb.append("").append(holiday.getSeq()).append(",").append(
                    holiday.getUserName()).append(",")
                    .append(holiday.getDays()).append(",").append(
                            holiday.getRemainingDays()).append("\r\n");
        }
        return sb.toString();
    }

    private void init() {
        holidays = PaidHolidayPeer.getPaidHolidayData(month);
        // Formを生成する
        final Form<PaidHolidayReport> form = new MainForm<PaidHolidayReport>(
                this, "wi_refPaidHolidayForm") {
            private static final long serialVersionUID = -7139946758481066937L;

            @Override
            protected void onSubmitInner() {
                super.onSubmitInner();
                log.info("選択した年月は" + sdf.format(month));
                holidays = PaidHolidayPeer.getPaidHolidayData(month);
            }

        };
        tblHoliday.setOutputMarkupId(true);
        form.add(tblHoliday);
        tblHoliday.add(new ListView<PaidHoliday>("wi_trPaidHoliday", holidays) {
            private static final long serialVersionUID = 4846361379394092695L;

            @Override
            protected void populateItem(ListItem<PaidHoliday> item) {
                final PaidHoliday holiday = item.getModelObject();
                item.add(new Label("wi_tdSeq", new PropertyModel<Integer>(
                        holiday, "seq")));
                item.add(new Label("wi_tdUsername", new PropertyModel<String>(
                        holiday, "userName")));
                item.add(new Label("wi_tdDays", new PropertyModel<Double>(
                        holiday, "days")));
                item.add(new Label("wi_tdRemainingDays",
                        new PropertyModel<Double>(holiday, "remainingDays")));
            }
        });

        wi_month.add(new DatePicker());
        wi_month.setOutputMarkupId(true);
        wi_month.add(new SimpleAttributeModifier("onChange",
                "forms[0].submit();"));

        WebResource csv = new WebResource() {
            private static final long serialVersionUID = -4726624638639655235L;

            @Override
            public IResourceStream getResourceStream() {
                String csv = toCSV();
                StringResourceStream srs = new StringResourceStream(csv,
                        "text/plain");
                srs.setCharset(Charset.forName(getString("contents.encoding")));
                return srs;
            }

            @Override
            protected void setHeaders(WebResponse response) {
                super.setHeaders(response);
                try {
                    response.setAttachmentHeader(new String("有給休暇一覧.csv"
                            .getBytes(), getString("filename.encoding")));
                } catch (UnsupportedEncodingException e) {
                    log.info(e.getLocalizedMessage());
                }
            }
        };
        form.add(new ResourceLink<Object>("wi_btnCSV", csv));

        csv.setCacheable(false);

        wi_btnNextMonth.setEnabled(false);
    }

}
